package net.zoneland.knowledge.config;

import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.pool.DruidDataSource;
import com.google.common.collect.Lists;
import io.lettuce.core.ConnectionState;
import org.checkerframework.checker.units.qual.min;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;

import java.util.Optional;

/**
 * 数据库属性配置对象.
 * @author zmq
 * @date 2021/8/17 16:50
 */
public class DataSourcePropsVO {
    private Boolean logSlowSql;
    private String url;
    private String driverClassName;
    private String username;
    private String password;
    private Long maxWait;
    private Integer minIdle = 5;
    private Integer initialSize = 5;
    private String validationQuery;
    private Integer maxActive = 10;
    private Boolean testOnBorrow;
    private Boolean testWhileIdle;
    private Long timeBetweenEvictionRunsMillis;
    private Boolean removeAbandoned;
    private Integer removeAbandonedTimeout;
//    jdbc-interceptors: ConnectionState;SlowQueryReport(threshold\=2000)
//    hibernate.temp.use_jdbc_metadata_defaults: false

    public Boolean getLogSlowSql() {
        return logSlowSql;
    }

    public void setLogSlowSql(Boolean logSlowSql) {
        this.logSlowSql = logSlowSql;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getDriverClassName() {
        return driverClassName;
    }

    public void setDriverClassName(String driverClassName) {
        this.driverClassName = driverClassName;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Long getMaxWait() {
        return maxWait;
    }

    public void setMaxWait(Long maxWait) {
        this.maxWait = maxWait;
    }

    public Integer getMinIdle() {
        return minIdle;
    }

    public void setMinIdle(Integer minIdle) {
        this.minIdle = minIdle;
    }

    public Integer getInitialSize() {
        return initialSize;
    }

    public void setInitialSize(Integer initialSize) {
        this.initialSize = initialSize;
    }

    public String getValidationQuery() {
        return validationQuery;
    }

    public void setValidationQuery(String validationQuery) {
        this.validationQuery = validationQuery;
    }

    public Integer getMaxActive() {
        return maxActive;
    }

    public void setMaxActive(Integer maxActive) {
        this.maxActive = maxActive;
    }

    public Boolean getTestOnBorrow() {
        return testOnBorrow;
    }

    public void setTestOnBorrow(Boolean testOnBorrow) {
        this.testOnBorrow = testOnBorrow;
    }

    public Boolean getTestWhileIdle() {
        return testWhileIdle;
    }

    public void setTestWhileIdle(Boolean testWhileIdle) {
        this.testWhileIdle = testWhileIdle;
    }

    public Long getTimeBetweenEvictionRunsMillis() {
        return timeBetweenEvictionRunsMillis;
    }

    public void setTimeBetweenEvictionRunsMillis(Long timeBetweenEvictionRunsMillis) {
        this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
    }

    public Boolean getRemoveAbandoned() {
        return removeAbandoned;
    }

    public void setRemoveAbandoned(Boolean removeAbandoned) {
        this.removeAbandoned = removeAbandoned;
    }

    public Integer getRemoveAbandonedTimeout() {
        return removeAbandonedTimeout;
    }

    public void setRemoveAbandonedTimeout(Integer removeAbandonedTimeout) {
        this.removeAbandonedTimeout = removeAbandonedTimeout;
    }

    @Override
    public String toString() {
        return "DataSourcePropsVO{" +
                "logSlowSql=" + logSlowSql +
                ", url='" + url + '\'' +
                ", driverClassName='" + driverClassName + '\'' +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", maxWait=" + maxWait +
                ", minIdle=" + minIdle +
                ", initialSize=" + initialSize +
                ", validationQuery='" + validationQuery + '\'' +
                ", maxActive=" + maxActive +
                ", testOnBorrow=" + testOnBorrow +
                ", testWhileIdle=" + testWhileIdle +
                ", timeBetweenEvictionRunsMillis=" + timeBetweenEvictionRunsMillis +
                ", removeAbandoned=" + removeAbandoned +
                ", removeAbandonedTimeout=" + removeAbandonedTimeout +
                '}';
    }

    /**
     * 初始化数据库相关属性.
     * @param druidDataSource
     */
    public void initProperties(DruidDataSource druidDataSource) {
        if(druidDataSource == null) {
            return;
        }
        Optional.ofNullable(this.logSlowSql).ifPresent(it -> {
            StatFilter filter = new StatFilter();
            filter.setLogSlowSql(it);
            druidDataSource.setProxyFilters(Lists.newArrayList(filter));
        });
        Optional.ofNullable(this.removeAbandoned).ifPresent(it -> {
            druidDataSource.setRemoveAbandoned(it);
        });
        Optional.ofNullable(this.driverClassName).ifPresent(it -> {
            druidDataSource.setDriverClassName(it);
        });
        Optional.ofNullable(this.initialSize).ifPresent(it -> {
            druidDataSource.setInitialSize(it);
        });
        Optional.ofNullable(this.maxActive).ifPresent(it -> {
            druidDataSource.setMaxActive(it);
        });
        Optional.ofNullable(this.maxWait).ifPresent(it -> {
            druidDataSource.setMaxWait(it);
        });
        Optional.ofNullable(this.minIdle).ifPresent(it -> {
            druidDataSource.setMinIdle(it);
        });
        Optional.ofNullable(this.password).ifPresent(it -> {
            druidDataSource.setPassword(it);
        });
        Optional.ofNullable(this.removeAbandonedTimeout).ifPresent(it -> {
            druidDataSource.setRemoveAbandonedTimeout(it);
        });
        Optional.ofNullable(this.testOnBorrow).ifPresent(it -> {
            druidDataSource.setTestOnBorrow(it);
        });
        Optional.ofNullable(this.testWhileIdle).ifPresent(it -> {
            druidDataSource.setTestWhileIdle(it);
        });
        Optional.ofNullable(this.timeBetweenEvictionRunsMillis).ifPresent(it -> {
            druidDataSource.setTimeBetweenEvictionRunsMillis(it);
        });
        Optional.ofNullable(this.url).ifPresent(it -> {
            druidDataSource.setUrl(it);
        });
        Optional.ofNullable(this.username).ifPresent(it -> {
            druidDataSource.setUsername(it);
        });
        Optional.ofNullable(this.validationQuery).ifPresent(it -> {
            druidDataSource.setValidationQuery(it);
        });
    }
}
